package backend.network.server.load;

import interfaces.rmi.client.IClientCallBack;

import java.rmi.RemoteException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

public class ConnectionManager
{

	private Collection<IClientCallBack> connections = null;
	private int counter = 0;

	public ConnectionManager()
	{
		this.connections = new Vector<IClientCallBack>();
	}

	// Get the lock on theadList, and wait until the counter is zero - that
	// is, no reads are taking place. Then it's safe to add the thread.
	public synchronized void add(IClientCallBack item)
	{
		try
		{
			while (counter > 0)
			{
				wait();
			}
			connections.add(item);
		} catch (InterruptedException e)
		{
			System.out.println("Addition interrupted.");
		} finally
		{
			notifyAll();
		}
	}

	// Similarly for removal.
	public synchronized void remove(IClientCallBack item)
	{
		try
		{
			while (counter > 0)
			{
				wait();
			}
			connections.remove(item);
		} catch (InterruptedException e)
		{
			System.out.println("Removal interrupted.");
		} finally
		{
			notifyAll();
		}
	}

	// Similarly for changing counter
	public synchronized void incCounter()
	{
		counter++;
		notifyAll();
	}

	public synchronized void decCounter()
	{
		counter--;
		notifyAll();
	}

	// This is because it would be too much effort to make this class implement
	// Collection, return it's own Iterator etc. etc...\
	// Note it is *not* a bug that it isn't synchronized
	public synchronized Collection<IClientCallBack> getCollection()
	{
		return connections;
	}

	public void login(IClientCallBack connection, String name) throws RemoteException
	{
		incCounter();
		System.out.println(connection + " connected.");

		connection.chat("fuck you!");

		connections.add(connection);

		for (Iterator<IClientCallBack> i = getCollection().iterator(); i.hasNext();)
		{
			IClientCallBack client = i.next();
			client.joinMessage(name);
		}
		decCounter();
	}

	public void leave(IClientCallBack n, String name) throws RemoteException
	{
		incCounter();
		connections.remove(n);

		for (Iterator<IClientCallBack> i = getCollection().iterator(); i.hasNext();)
		{
			IClientCallBack client = i.next();
			client.exitMessage(name);
		}
		decCounter();
	}
}